<template>
  <div class="ReceiptPrinter" v-if="showButton">
    <el-button type="primary" :disabled="!canPrint" @click="print">打印小票</el-button>
  </div>
</template>
<script setup>
/**
 * 通用小票打印组件
 * Props:
 *  - order: { orderNo, customerName, orderDate, note, totalAmount, items: [{name, quantity, unitPrice, totalPrice}] }
 *  - paperWidth: 纸宽 mm (默认 58)
 *  - showButton: 是否显示内置按钮
 * 暴露方法: print()
 */
import {computed, toRefs, defineProps, defineExpose} from 'vue'
import {ElMessage} from 'element-plus'

const props = defineProps({
  order: { type: Object, default: () => ({}) },
  paperWidth: { type: Number, default: 58 },
  showButton: { type: Boolean, default: true }
})

const { order, paperWidth, showButton } = toRefs(props)

const canPrint = computed(() => !!order.value && Array.isArray(order.value.items) && order.value.items.length > 0)

const formatMoney = v => Number(v || 0).toFixed(2)
const esc = s => (s == null ? '' : String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'))

const buildHtml = () => {
  const o = order.value || {}
  const items = Array.isArray(o.items) ? o.items : []
  const itemsHTML = items.map((it,i) => {
    const name = esc(it.name).slice(0,14)
    const qty = Number(it.quantity||0).toFixed(2)
    const price = Number(it.unitPrice||0).toFixed(2)
    const total = Number(it.totalPrice||0).toFixed(2)
    return `<div class="row"><span class="col name">${i+1}.${name}</span><span class="col qty">${qty}</span><span class="col price">${price}</span><span class="col total">${total}</span></div>`
  }).join('')
  return `<!DOCTYPE html><html><head><meta charset='utf-8'/><title>小票</title><style>
    @page { size: ${paperWidth.value}mm auto; margin:0; }
    * { box-sizing:border-box; }
    body { width:${paperWidth.value}mm; margin:0; padding:6px 6px 10px; font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif; font-size:12px; }
    .center{text-align:center;} .title{font-size:14px;font-weight:700;margin-bottom:4px;} .meta{margin-bottom:4px;line-height:1.3;}
    .hr{border-top:1px dashed #000;margin:4px 0;} .header,.row{display:flex;width:100%;} .header span{font-weight:600;}
    .col{flex-shrink:0;} .name{flex:1 1 auto;overflow:hidden;} .qty{width:40px;text-align:right;} .price{width:50px;text-align:right;} .total{width:56px;text-align:right;}
    .summary{text-align:right;margin-top:4px;font-weight:600;} .small{text-align:center;font-size:10px;margin-top:6px;}
  </style></head><body>
  <div class='center title'>销售小票</div>
  <div class='meta'>订单: ${esc(o.orderNo)}<br/>客户: ${esc(o.customerName)||'-'}<br/>日期: ${esc(o.orderDate)||'-'}<br/>备注: ${esc(o.note||'-')}</div>
  <div class='hr'></div>
  <div class='header'><span class='col name'>品名</span><span class='col qty'>数量</span><span class='col price'>单价</span><span class='col total'>小计</span></div>
  <div class='hr'></div>
  ${itemsHTML}
  <div class='hr'></div>
  <div class='summary'>合计: ¥ ${formatMoney(o.totalAmount)}</div>
  <div class='small'>谢谢惠顾</div>
  <script>window.print();setTimeout(()=>window.close(),300);<\/script>
  </body></html>`
}

const print = () => {
  if (!canPrint.value) return ElMessage.warning('无可打印明细')
  const win = window.open('', '_blank', 'width=420,height=600')
  if (!win) { ElMessage.warning('请允许弹出窗口'); return }
  win.document.write(buildHtml())
  win.document.close()
}

defineExpose({ print })
</script>
<style scoped>
.ReceiptPrinter { display:inline-block; }
</style>

